document.addEventListener('DOMContentLoaded', () => { const yearEl = document.querySelector('#currentYear'); if (yearEl) { yearEl.textContent = new Date().getFullYear(); } const topbar = document.querySelector('.topbar'); let lastScrollY = window.scrollY; let scrollTimeout; function updateTopbarState() { if (!topbar) return; const currentY = window.scrollY; if (currentY > lastScrollY + 10 && currentY > 40) { topbar.classList.add('topbar--hidden'); } else if (currentY < lastScrollY - 10 || currentY <= 40) { topbar.classList.remove('topbar--hidden'); } if (currentY > 12) { topbar.classList.add('topbar--shadow'); } else { topbar.classList.remove('topbar--shadow'); } lastScrollY = currentY; } function onScroll() { if (scrollTimeout) { window.cancelAnimationFrame(scrollTimeout); } scrollTimeout = window.requestAnimationFrame(updateTopbarState); } window.addEventListener('scroll', onScroll, { passive: true }); const copyButton = document.querySelector('[data-copy-pix]'); const pixKeyEl = document.querySelector('[data-pix-key]'); let toastEl; function showToast(message) { if (!toastEl) { toastEl = document.createElement('div'); toastEl.className = 'toast'; document.body.appendChild(toastEl); } toastEl.textContent = message; toastEl.classList.add('toast--visible'); window.setTimeout(() => { toastEl.classList.remove('toast--visible'); }, 2500); } if (copyButton && pixKeyEl) { copyButton.addEventListener('click', async () => { const key = pixKeyEl.textContent.trim(); if (!key) return; try { await navigator.clipboard.writeText(key); showToast('Chave PIX copiada!'); window.alert('Copiado! Agora é só colar no app do seu banco e finalizar sua ajuda 🧡'); } catch (error) { const fallbackMsg = 'Não foi possível copiar automaticamente. Copie manualmente: ' + key; showToast(fallbackMsg); window.alert(fallbackMsg); } }); } const faqItems = Array.from(document.querySelectorAll('.faq-item')); if (faqItems.length) { faqItems.forEach((item) => { const question = item.querySelector('.faq-question'); if (!question) return; question.setAttribute('aria-expanded', 'false'); question.addEventListener('click', () => { const isOpen = item.classList.contains('open'); faqItems.forEach((other) => { if (other !== item) { other.classList.remove('open'); const otherBtn = other.querySelector('.faq-question'); if (otherBtn) { otherBtn.setAttribute('aria-expanded', 'false'); } } }); if (!isOpen) { item.classList.add('open'); question.setAttribute('aria-expanded', 'true'); } else { item.classList.remove('open'); question.setAttribute('aria-expanded', 'false'); } }); }); } // ===== MODAL CNPJ ===== window.openCnpjModal = function () { const modal = document.getElementById('cnpjModal'); if (modal) { modal.offsetHeight; modal.classList.add('show'); document.body.style.overflow = 'hidden'; } }; window.closeCnpjModal = function () { const modal = document.getElementById('cnpjModal'); if (modal) { modal.classList.remove('show'); document.body.style.overflow = 'auto'; } }; // Fechar modal ao clicar fora da imagem const cnpjModal = document.getElementById('cnpjModal'); if (cnpjModal) { cnpjModal.addEventListener('click', (e) => { if (e.target === cnpjModal) { window.closeCnpjModal(); } }); } // ========== CARROSSEL DE CARDS DE DOAÇÃO (LOOP INFINITO) ========== const cardsTrack = document.querySelector('.cards-track'); const cardsContainer = document.querySelector('.cards-slider-container'); const cardsPrevBtn = document.querySelector('.cards-arrow-prev'); const cardsNextBtn = document.querySelector('.cards-arrow-next'); const cardGap = 12; const totalRealCards = 5; let currentIndex = 1; // Começa no índice 1 (primeiro card real, após o clone) let isTransitioning = false; // Clonar cards para criar loop infinito verdadeiro function setupInfiniteLoop() { if (!cardsTrack) return; const cards = cardsTrack.querySelectorAll('.donation-card:not(.clone)'); if (cards.length === 0) return; // Clona o último card e coloca no início const lastClone = cards[cards.length - 1].cloneNode(true); lastClone.classList.add('clone'); cardsTrack.insertBefore(lastClone, cards[0]); // Clona o primeiro card e coloca no final const firstClone = cards[0].cloneNode(true); firstClone.classList.add('clone'); cardsTrack.appendChild(firstClone); } function getCardWidth() { const card = cardsTrack.querySelector('.donation-card'); return card ? card.offsetWidth : 240; } function updateCardsSlider(animate = true) { if (!cardsTrack || !cardsContainer) return; const cardWidth = getCardWidth(); const containerWidth = cardsContainer.offsetWidth; const centerOffset = (containerWidth - cardWidth) / 2; const offset = currentIndex * (cardWidth + cardGap) - centerOffset; if (animate) { cardsTrack.style.transition = 'transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)'; } else { cardsTrack.style.transition = 'none'; } cardsTrack.style.transform = `translateX(-${offset}px)`; } function goToNextCard() { if (isTransitioning) return; isTransitioning = true; currentIndex++; updateCardsSlider(true); // Fallback timeout caso transitionend não dispare setTimeout(() => { handleTransitionEnd(); }, 450); } function goToPrevCard() { if (isTransitioning) return; isTransitioning = true; currentIndex--; updateCardsSlider(true); // Fallback timeout caso transitionend não dispare setTimeout(() => { handleTransitionEnd(); }, 450); } // Verifica se precisa fazer o "snap" do loop infinito function handleTransitionEnd() { if (!isTransitioning) return; // Evita executar duas vezes isTransitioning = false; // Se foi para o clone do final (após o último card real) if (currentIndex >= totalRealCards + 1) { // Aguarda um frame antes do snap para garantir que a animação terminou requestAnimationFrame(() => { cardsTrack.style.transition = 'none'; currentIndex = 1; updateCardsSlider(false); // Força reflow cardsTrack.offsetHeight; }); } // Se foi para o clone do início (antes do primeiro card real) else if (currentIndex <= 0) { // Aguarda um frame antes do snap para garantir que a animação terminou requestAnimationFrame(() => { cardsTrack.style.transition = 'none'; currentIndex = totalRealCards; updateCardsSlider(false); // Força reflow cardsTrack.offsetHeight; }); } } if (cardsTrack) { cardsTrack.addEventListener('transitionend', (e) => { // Só processa se for o próprio track if (e.target === cardsTrack) { handleTransitionEnd(); } }); } if (cardsPrevBtn) { cardsPrevBtn.addEventListener('click', goToPrevCard); } if (cardsNextBtn) { cardsNextBtn.addEventListener('click', goToNextCard); } // Touch/Swipe support para mobile let touchStartX = 0; let touchEndX = 0; if (cardsContainer) { cardsContainer.addEventListener('touchstart', (e) => { touchStartX = e.changedTouches[0].screenX; }, { passive: true }); cardsContainer.addEventListener('touchend', (e) => { touchEndX = e.changedTouches[0].screenX; handleSwipe(); }, { passive: true }); } function handleSwipe() { const swipeThreshold = 50; const diff = touchStartX - touchEndX; if (diff > swipeThreshold) { goToNextCard(); } else if (diff < -swipeThreshold) { goToPrevCard(); } } // Atualizar ao redimensionar a janela let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { updateCardsSlider(false); }, 100); }); // Inicializar - cria os clones e posiciona setupInfiniteLoop(); setTimeout(() => updateCardsSlider(false), 50); // ===== FUNÇÃO PARA SCROLL SUAVE PARA SEÇÃO PIX (CENTRALIZADA) ===== window.scrollToPix = function() { const pixSection = document.getElementById('doe'); if (pixSection) { // Calcula a posição para centralizar a seção na tela const elementPosition = pixSection.getBoundingClientRect().top + window.pageYOffset; const offsetPosition = elementPosition - (window.innerHeight / 2) + (pixSection.offsetHeight / 2); window.scrollTo({ top: offsetPosition, behavior: 'smooth' }); } }; // ===== FUNÇÃO PARA SCROLL SUAVE PARA SEÇÃO NOSSA HISTÓRIA ===== window.scrollToStory = function() { const storySection = document.getElementById('sobre'); if (storySection) { storySection.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }; // ===== MOSTRAR BOTÃO FIXO APENAS QUANDO COMEÇAR A SEÇÃO SALVE CÃO ===== const fixedMobileButton = document.getElementById('fixedMobileButton'); const salveCaoSection = document.getElementById('salve-cao-section'); if (fixedMobileButton && salveCaoSection) { function updateFixedButtonVisibility() { // Só mostra em mobile if (window.innerWidth > 768) { fixedMobileButton.style.display = 'none'; return; } const rect = salveCaoSection.getBoundingClientRect(); // Se a seção "Salve Cão" já começou a aparecer (top <= window.innerHeight) if (rect.top <= window.innerHeight) { fixedMobileButton.style.display = 'block'; } else { fixedMobileButton.style.display = 'none'; } } // Verifica no scroll window.addEventListener('scroll', updateFixedButtonVisibility, { passive: true }); // Verifica no resize window.addEventListener('resize', updateFixedButtonVisibility, { passive: true }); // Verifica inicialmente updateFixedButtonVisibility(); } });